#include <getopt.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <stddef.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>

#include "cJSON.h"

#include "debug.h"
int g_dbg_lvl = DBG_LEVEL_INFO;

#define MAX_CONFIGFILE 4*1024*1024L

DEBUG_LEVEL get_dbg_level (void)
{
  return g_dbg_lvl;
}
void set_dbg_level (DEBUG_LEVEL dbg_level)
{
  DBG_INFO ("Set Debug Level as %d", dbg_level);

  g_dbg_lvl = dbg_level;
}

int revers_modify(cJSON * node,char * settingName,char * setvalue )
{
    if(node->child != NULL)
    {

    }
    else
    {

    }
    //return 0;
}

int peer_modify(cJSON *node,char *settingName,int  setvalue)
{
    if(node->next != NULL)
    {
        //DBG_INFO("node->next != NULL");
        DBG_INFO("node->next!=NULL--%s--",node->string);
        peer_modify(node->next,settingName,setvalue);
    }
    else
    {
        DBG_INFO("node->next==NULL--%s--",node->string);
        if(node->child != NULL)
        {
            DBG_INFO("node->child peer_modify");
            peer_modify(node->child,settingName,setvalue);
            
        }
        else
        {   
            if(strcmp(node->string,"Memory Clock") == 0)
            {
                //DBG_INFO("--%s--",node->string);
                DBG_INFO("--%s-- %s",node->string,node->valuestring);
            }
            DBG_INFO("--%s-- %s",node->string,node->valuestring);
            return  0;
        }
    }

}
int peer_modify4(cJSON *node,char *settingName,int  setvalue)
{
    cJSON * tmp_node;
    tmp_node = node;

    cJSON * p_a;
    cJSON * p_b;
    while (tmp_node != NULL)
    {
        //DBG_INFO("--%s-- %s",tmp_node->string,tmp_node->valuestring);
        if( (strcmp(tmp_node->string,settingName)==0 ) && (strlen(tmp_node->string) == strlen(settingName) ))
        {
            DBG_INFO("OUT--%s-- %d",tmp_node->string,tmp_node->type);   
            p_a = tmp_node->child;
            while (p_a)
            {
                if(p_a->type == 3  && strcmp(p_a->string,"value") == 0  )
                {
                    //DBG_INFO("value before --%ld--",p_a->valueint);
                    //p_a->valueint = setvalue;
                    cJSON_SetIntValue(p_a,setvalue);
                    //DBG_INFO("value after --%ld--",p_a->valueint);
                    break;
                }
                p_a = p_a->next;
            }
            break;
        }

        //if(tmp_node->child != NULL && tmp_node->child->child != NULL)
        if(tmp_node->child != NULL )
        {
            peer_modify4(tmp_node->child,settingName,setvalue);

            //DBG_INFO("--%s-- %s",tmp_node->string,tmp_node->valuestring);
            tmp_node = tmp_node->next;
        }
        else
        {
            tmp_node = tmp_node->next;
            continue;
        }

        //tmp_node = tmp_node->next;
    }
   
    
}


int peer_print4(cJSON *node,char *settingName,int  setvalue)
{
    cJSON * tmp_node;
    tmp_node = node;
    //DBG_INFO("OUT--peer_print4");
    cJSON * p_a;
    cJSON * p_b;
    while (tmp_node != NULL)
    {
        //DBG_INFO("--%s-- %s",tmp_node->string,tmp_node->valuestring);
        if(strstr(tmp_node->string,settingName) )
        {
            DBG_INFO("OUT--%s-- %d",tmp_node->string,tmp_node->type);   
            p_a = tmp_node->child;
            while (p_a)
            {
                if(p_a->type == 3  && strcmp(p_a->string,"value") == 0  )
                {
                    //DBG_INFO("value --%lx--",p_a->valueint);
                    printf("printf_value --%ld--\n",p_a->valueint);
                    p_b = p_a;
                    //break;
                }
                p_a = p_a->next;
            }
            break;
        }

        //if(tmp_node->child != NULL && tmp_node->child->child != NULL)
        if(tmp_node->child != NULL )
        {
            peer_print4(tmp_node->child,settingName,setvalue);

            //DBG_INFO("--%s-- %s",tmp_node->string,tmp_node->valuestring);
            tmp_node = tmp_node->next;
        }
        else
        {
            tmp_node = tmp_node->next;
            continue;
        }

        //tmp_node = tmp_node->next;
    }
   
    
}


int main(int argc, char* argv[])
{
    FILE *fHanle = NULL;
    int filelen=0;
    //char buff[MAX_CONFIGFILE];
    char * buff=NULL;
    char  ttttmp[256];
    if(argc != 4)
    {
        DBG_INFO("Wrong Parameters");
        DBG_INFO("the usage:");
        DBG_INFO("          %s  configpath settingname  value ",argv[0]);
        return 0;
    }
    //DBG_INFO("Start Parse -%s- -%s-  -%s-  %s--%d--\n",argv[1],argv[2],argv[3],argv[4],argc);
    buff=calloc(1,MAX_CONFIGFILE);
    if(buff==NULL)
    {
        DBG_INFO("malloc error");
        return -1;
    }

    fHanle = fopen(argv[1], "r+");
    if (NULL == fHanle)
    {
        DBG_ERR("Open config Fail r+");
        return -1;
    }
    fseek(fHanle,0L, SEEK_END);
    filelen = ftell(fHanle);
    //DBG_INFO("file length %d",filelen);
    fseek(fHanle,0L, SEEK_SET);

    memset(buff,0,sizeof(MAX_CONFIGFILE));
    fread(buff,1,filelen,fHanle);

    fclose(fHanle);
    fHanle = NULL;

    fHanle = fopen(argv[1], "w+");
    if (NULL == fHanle)
    {
        DBG_ERR("Open config Fail w+");
        return -1;
    }
    //cJSON* cjson_test = NULL; 
    cJSON *jsonData = cJSON_Parse(buff);
    if(jsonData  == NULL){
	    DBG_INFO("json pack into cjson error..\n.");
    }
    int  mod_int;

    mod_int = strtol(argv[3], NULL, 0x0);

    peer_modify4(jsonData->child,argv[2],mod_int);
    char * config_write;
    config_write = cJSON_Print(jsonData);

    //FILE *fHanle2 = NULL;
    //fHanle2 = fopen("./config_test.json", "w+");
    fseek(fHanle,0L, SEEK_SET);
    fwrite(config_write,1,strlen(config_write),fHanle);
    //memset(ttttmp,0,sizeof(ttttmp));
    //fwrite(ttttmp,1,4,fHanle);
    //DBG_INFO("strlen(config_write) ---%d---    filelen--%d--  ",strlen(config_write),filelen);
 
    //fclose(fHanle2);
    //peer_print4(jsonData->child,"Pstate4 FID",44);


    free(config_write);
    cJSON_Delete(jsonData);

    fflush(fHanle);
    fclose(fHanle);

    if(buff != NULL)
    {
        free(buff);
    }

    return 0;
}
/*
 gcc main.c cJSON.c -lm

*/